home *** CD-ROM | disk | FTP | other *** search
/ Greenhouse Effect Detection Expriment / NASA Greenhouse Effect Detection Expriment 1992 - Disc 2.iso / software / dos / cdf22pc / src / tools / wfl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-03  |  44.9 KB  |  1,808 lines

  1. /******************************************************************************
  2. *
  3. *  NSSDC/CDF                    Window Function Library.
  4. *
  5. *  Version 2.0, 4-Mar-92, ST Systems (STX)
  6. *
  7. *  Modification history:
  8. *
  9. *   V1.0  29-Jan-91, C Goettsche
  10. *             D Grogan
  11. *             H Leckner        Original version (for CDF V2.0).
  12. *   V1.1  25-Jun-91, J Love        Removed 'kb_def_user.h'.
  13. *   V1.2  28-Jun-91, J Love        TRUE/FALSE.
  14. *   V2.0   4-Mar-92, J Love        Modified for IBM-PC port.  CDF V2.2.
  15. *             H Leckner
  16. *
  17. ******************************************************************************/
  18.  
  19. #include "wfl.h"
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. #include "cdfdist.h"
  24. #include "kb_def.h"
  25. #include "utility.h"
  26.   /*
  27.    *    development debug switches
  28.    */
  29. #define KEYPADBUG (0)
  30. #define DEBUG     (0)
  31. #define DEBUG1    (0)
  32. #define DEBUG2    (0)
  33. #define DEBUG3    (0)
  34. #define DEBUG4    (0)
  35.  
  36.   /*
  37.    *    these debug WFL_load_menu scrolling capability
  38.    */
  39. #define MARKLOAD   (0)    /* send slow-motion message on each put_char */
  40. #define UPDATE_ON  (1)    /* display_update on or off  */
  41.  
  42.  
  43. #define MAX_MENUS 35      /* Constants for */
  44. #define TRANSIENT  0      /* WFL_popup_menu() */
  45.  
  46. #define GP (**c)
  47. #define CP (*c)
  48.  
  49. #define CURSOR_OFF     1
  50. #define CURSOR_ON      0
  51.  
  52. /*  The next mark, clsPAREN,  will only be used to close function headers.
  53.     This has been done so that the *.REF can be extracted and used
  54.     as the ANSI function prototype list by redefining clsPAREN as );
  55.     The prototypes (file WFL.REF) is included by WFL.H so the define
  56.     below must come after the include for "wfl.c"
  57. */
  58.  
  59. #define clsPAREN  )
  60.  
  61.                            /*CodeRef-mark*/
  62.   /*
  63.    *   Global screen functions
  64.    */
  65.  
  66. #if defined(unix)
  67. void left_justify();
  68. #else
  69. void left_justify (char  field[], int  len);
  70. #endif
  71.                            /*CodeRef-mark*/
  72.  
  73. void WFL_init()
  74. /*
  75.  *  Call this once before using any of the other WFL functions to
  76.  *  initialize the global_struct.
  77.  *  This function intializes the screen driver and keyboard controller.
  78.  *  The pointers to these devices are held in a structure which is allocated
  79.  *  and passed back to the caller.  This pointer must be passed into most
  80.  *  WFL routines.
  81.  */
  82.                            /*CodeRef-mark*/
  83. {
  84.     create_pasteboard();  /* OK as is for vms 5 SMG; pasteboard always
  85.                 before keyboard - grogan 12/21/89 */
  86.  
  87. #ifdef vms
  88.     set_keypad_mode (1L);  /* 1= application keyboard */
  89.                  /* 0= numeric keyboard */
  90. #endif
  91.  
  92. }  /* end WFL_init */
  93.  
  94.  
  95.                            /*CodeRef-mark*/
  96.  
  97. void WFL_close()
  98. /*
  99.  *  This function terminates a session with the WFL package and should
  100.  *  be called after the interface is completed.
  101.  *  c is the pointer used when WFL_init() was called.
  102.  */
  103.                            /*CodeRef-mark*/
  104. {
  105.     int    erase_mode;
  106.     erase_mode = 1;
  107.     delete_pasteboard(erase_mode);
  108.  
  109. }  /*  end WFL_close  */
  110.  
  111.  
  112.                            /*CodeRef-mark*/
  113.  
  114. #if defined(vms)
  115. void WFL_message_init(mess_ptr)
  116. struct  window_struct    *mess_ptr;
  117. /*
  118.  *  This function initializes a message window pointed to by mess_ptr
  119.  *  so that operating system messages will be trapped and sent to that
  120.  *  window.  Otherwise, system messages would appear wherever the cursor
  121.  *  happened to be.
  122.  */
  123.                            /*CodeRef-mark*/
  124. {
  125.  
  126. WINDOWid    mess_id;
  127.  
  128.     mess_id = (*mess_ptr).wind_id;
  129.  
  130.     enable_trap(mess_id);
  131.  
  132. }  /*  end WFL_message_init  */
  133. #endif
  134.  
  135.                            /*CodeRef-mark*/
  136.  
  137. void WFL_message_display (c ,message, beep)
  138. struct  window_struct    *c;
  139. char            message[];
  140. int            beep;
  141. /*
  142.  *  This function displays the string message[] in the message window c.
  143.  *  The "beep" parameter determines wheteher the terminal beeps or not
  144.  *  when the message is sent.  beep should be one of the predefined
  145.  *  constants BEEP or NOBEEP.
  146.  */
  147.                            /*CodeRef-mark*/
  148. {
  149.     int    erase_mode = 0;
  150.     int    video_type = NORMAL;
  151.     int    len;
  152.     int    start_row = 1;
  153.     int    start_col = 1;
  154.  
  155.     len = strlen(message);
  156.     put_chars(CP.wind_id, message, len, start_row, start_col,
  157.              erase_mode, video_type);
  158.     if (beep)
  159. #if defined(vms)
  160.     ring_bell (CP.wind_id);
  161. #else
  162.     ring_bell();
  163. #endif
  164. }  /*  end  WFL_message_display  */
  165.  
  166.  
  167.                            /*CodeRef-mark*/
  168.  
  169. void WFL_begin_screen_update ()
  170. /*
  171.  *  Prepare screen for updating in a buffer.
  172.  */
  173.                            /*CodeRef-mark*/
  174. {
  175. #if defined(vms)
  176.     begin_pasteboard_update();
  177. #endif
  178. }  /*  end WFL_begin_screen_update  */
  179.  
  180.                            /*CodeRef-mark*/
  181.  
  182. void WFL_end_screen_update ()
  183. /*
  184.  *  This function flushes the buffer after a call to WFL_begin_screen_update.
  185.  *  Used to maintain data abstraction.
  186.  */
  187.                            /*CodeRef-mark*/
  188. {
  189. #if defined(vms)
  190.     end_pasteboard_update();
  191. #endif
  192. }  /*  end WFL_end_screen_update  */
  193.  
  194.  
  195.  
  196.                            /*CodeRef-mark*/
  197.   /*
  198.    *   General window functions, for all window types
  199.    */
  200.  
  201.                            /*CodeRef-mark*/
  202.  
  203.  
  204.                            /*CodeRef-mark*/
  205.  
  206. void WFL_create_window( c)
  207. struct  window_struct    *c ;
  208. /*
  209.  *  This function will initialize a window for further use in WFL.
  210.  *  The window_struct c should have its elements num_rows and num_cols
  211.  *  assigned before calling WFL_create_window().
  212.  */
  213.                            /*CodeRef-mark*/
  214. {
  215.     WINDOWid        vid;
  216.     int            disp_type;
  217.     int            video_type;
  218.  
  219.     disp_type = 1;
  220.     video_type = NORMAL;  /* changed from _ONE (BOLD) */
  221.     create_virtual_display(CP.num_rows+ROW_OFFSET, CP.num_cols+COL_OFFSET,
  222.             &vid, disp_type, video_type);
  223.     CP.wind_id = vid;
  224.  
  225. }  /*  end WFL_create_window  */
  226.  
  227.                            /*CodeRef-mark*/
  228.  
  229. void WFL_delete_window(c)
  230. struct  window_struct    *c ;
  231. /*
  232.  *  Remove the window for good -- complement of WFL_create_window.
  233.  *  Not the same as WFL_erase_window().
  234.  *  The window cannot be used again without re-creating it.
  235.  *  See WFL_erase_display to "clear" the window.
  236.  */
  237.                            /*CodeRef-mark*/
  238. {
  239.     WINDOWid    vid;
  240.  
  241.     vid = CP.wind_id;
  242.     delete_virtual_display( vid );
  243.  
  244. }  /*  end WFL_delete_window  */
  245.  
  246.  
  247.  
  248.                            /*CodeRef-mark*/
  249.  
  250. void WFL_draw_window (window_ptr)
  251. struct  window_struct   *window_ptr;
  252. /*
  253.  *  This function draws a labeled window on the screen at the
  254.  *  location and with the dimensions given within the window_struct.
  255.  *  The label element in the window_struct is used to create
  256.  *  a label for the window border.  You may use a null string label for an
  257.  *  unlabeled window.
  258.  *  At this point the window is an empty box which may now be written to.
  259.  *  The drawn window will occlude other text on the screen until the
  260.  *  window is moved or erased.
  261.  */
  262.                            /*CodeRef-mark*/
  263. {
  264.     int        len;
  265.  /*
  266. #if !defined(vms)
  267. begin_display_update((*window_ptr).wind_id);
  268. #endif
  269. */
  270.     paste_virtual_display((*window_ptr).wind_id,
  271.     (*window_ptr).start_row-ROW_OFFSET,(*window_ptr).start_col-COL_OFFSET);
  272.  
  273.     len = strlen((*window_ptr).label);
  274.     if (len > 0)
  275.     label_border((*window_ptr).wind_id, (*window_ptr).label, len);
  276. /*
  277. #if |defined(vms)
  278. end_display_update((*window_ptr).wind_id);
  279. #endif
  280. */
  281. }  /*  end WFL_draw_window  */
  282.  
  283.  
  284.                            /*CodeRef-mark*/
  285.  
  286. void WFL_erase_window (window_ptr)
  287. struct  window_struct   *window_ptr;
  288. /*
  289.  *  This function erases window (pointed to by window_ptr) from
  290.  *  the video display -- the inverse of WFL_draw_window().
  291.  *  Not the same as WFL_erase_display() or WFL_delete_window().
  292.  *  Any text on the screen which had been occluded by the window will
  293.  *  be restored to the screen.
  294.  *  The erased window still exists and can be displayed again
  295.  *  with WFL_draw_window() until it is deleted with WFL_delete_window().
  296.  */
  297.                            /*CodeRef-mark*/
  298. {
  299.     unpaste_virtual_display((*window_ptr).wind_id);
  300.  
  301. }  /* end WFL_erase_window */
  302.  
  303.  
  304.  
  305.                            /*CodeRef-mark*/
  306.  
  307. void WFL_erase_display (window_ptr)
  308. struct window_struct  *window_ptr;
  309. /*
  310.  *  This function will erase (clear) the display in the window --
  311.  *  that is, it will amke the interior of the window all blanks.
  312.  *  The window and its border still remain active and displayed.
  313.  *  Not the same as WFL_erase_window() or WFL_delete_window().
  314.  */
  315.                            /*CodeRef-mark*/
  316. {
  317.         erase_display ((*window_ptr).wind_id, 1, 1,
  318.                         (*window_ptr).num_rows,
  319.                         (*window_ptr).num_cols);
  320. }   /* end WFL_erase_display */
  321.  
  322.  
  323.  
  324.                            /*CodeRef-mark*/
  325. void WFL_begin_display_update (window_ptr)
  326. struct  window_struct   *window_ptr;
  327. /*
  328.  *  This function starts buffering of output to the window
  329.  *  for smoother onscreen appearance.  Actual device output
  330.  *  is not done until you call WFL_end_display_update().
  331.  *  Return value: void.
  332.  */
  333.                            /*CodeRef-mark*/
  334. {
  335.        begin_display_update((*window_ptr).wind_id);
  336. }
  337.  
  338.                            /*CodeRef-mark*/
  339.  
  340. void WFL_end_display_update (window_ptr)
  341. struct  window_struct   *window_ptr;
  342. /*
  343.  *  This function flushes the buffering started by
  344.  *  WFL_begin_display_update().
  345.  *  Return value: void.
  346.  */
  347.                            /*CodeRef-mark*/
  348. {
  349.        end_display_update((*window_ptr).wind_id);
  350. }
  351. #if !defined(vms)
  352. void WFL_end_display_update_nobox(window_ptr)
  353. struct  window_struct   *window_ptr;
  354. /*
  355.  *  This function flushes the buffering started by
  356.  *  WFL_begin_display_update().
  357.  *  this is a special version needed because of labels being overwritten
  358.  *  in some cases
  359.  *  Return value: void.
  360.  */
  361.                            /*CodeRef-mark*/
  362. {
  363.        end_display_update_nobox((*window_ptr).wind_id);
  364. }
  365. #endif
  366.  
  367.                            /*CodeRef-mark*/
  368.  
  369. void WFL_change_window_length ( c, length)
  370. struct  window_struct    *c;
  371. int        length;
  372. /*
  373.  *  Rewrite length (num_rows) of window.
  374.  *  Used to maintain data abstraction.
  375.  */
  376.                            /*CodeRef-mark*/
  377. {
  378.     CP.num_rows = length;
  379. }  /*  end WFL_change_window_length  */
  380.  
  381.  
  382.                            /*CodeRef-mark*/
  383.  
  384. void WFL_change_window_width ( c, width)
  385. struct  window_struct    *c;
  386. int        width;
  387. /*
  388.  *  Rewrite width (num_cols) of window.
  389.  *  Used to maintain data abstraction.
  390.  */
  391.                            /*CodeRef-mark*/
  392. {
  393.     CP.num_cols = width;
  394. }  /*  end WFL_change_window_length  */
  395.  
  396.  
  397.                            /*CodeRef-mark*/
  398.  
  399. void WFL_change_window_loc ( c, x, y)
  400. struct  window_struct    *c;
  401. int        x;
  402. int        y;
  403. /*
  404.  *  Alter starting location of window (x is start_col; y is start_row).
  405.  *  Used to maintain data abstraction.
  406.  */
  407.                            /*CodeRef-mark*/
  408.  
  409. {
  410.     CP.start_col = x;
  411.     CP.start_row = y;
  412. }  /*  end WFL_change_window_loc */
  413.  
  414.  
  415.  
  416.  
  417.                            /*CodeRef-mark*/
  418.   /*
  419.    *     Menu functions
  420.    */
  421.  
  422.  
  423.                            /*CodeRef-mark*/
  424.  
  425.                            /*CodeRef-mark*/
  426.  
  427. void WFL_menu_element (data_ptr, element_ptr, num_elements, number, rcode )
  428. char                     data_ptr[];
  429. struct  menu_element_struct  *element_ptr[];
  430. int                 num_elements;
  431. int                 *number;
  432. int                 *rcode;
  433. /*
  434.  *  This function tells the index number of a menu element string.
  435.  *  The string to look for is passed in by data_ptr and is compared
  436.  *  to all elements strings pointed to in element_ptr[].
  437.  *  The number of elements must be given.
  438.  *  If a match found, the element number is returned in the
  439.  *  variable "number", otherwise a -1 is returned by rcode.
  440.  *  This function is the inverse of WFL_menu_string().
  441.  *
  442.  */
  443.                            /*CodeRef-mark*/
  444. {
  445.     int            element_num;
  446.     int            len;
  447.     int            check;
  448.     *rcode = 0;
  449.     len = strlen(data_ptr);
  450.     if(len > 0)
  451.  
  452.        {
  453.        for (element_num = 0; element_num < num_elements; ++element_num)
  454.         {
  455.         check = strcmp(data_ptr, (*element_ptr[element_num]).label);
  456.         if(check == 0)
  457.            {
  458.            *number = element_num;
  459.            return;
  460.            }
  461.         }
  462.         *rcode = -1;
  463.        }
  464.  
  465. }  /*  end WFL_menu_element  */
  466.  
  467.  
  468.                            /*CodeRef-mark*/
  469.  
  470. void WFL_menu_string (index, element_ptr, string)
  471. int                   index;
  472. struct  menu_element_struct   *element_ptr[];
  473. char                   string[];
  474. /*
  475.  *  This function copies the menu element specified by index into
  476.  *  the array string[].
  477.  *  rcode is not used.
  478.  *  This function is the inverse of WFL_menu_element().
  479.  */
  480.                            /*CodeRef-mark*/
  481. {
  482.     string = strcpy(string, (*element_ptr[index]).label);
  483. }  /*  end WFL_menu_string  */
  484.  
  485.  
  486.  
  487.                            /*CodeRef-mark*/
  488.  
  489. void WFL_load_menu (element_ptr, num_elements, window_ptr,
  490.             rowOffset, colOffset)
  491. struct  menu_element_struct  *element_ptr[];
  492. int                  num_elements;
  493. struct  window_struct        *window_ptr;
  494. int                       rowOffset;
  495. int                          colOffset;
  496. /*
  497.  *  This function loads a menu.
  498.  */
  499.                            /*CodeRef-mark*/
  500. {
  501.     int            element_num;
  502.     int            erase_mode;
  503.     int            video_type;
  504.     int            len;
  505.  
  506.     int            srow, scol;
  507.  
  508. #if MARKLOAD
  509.  char message[200];
  510.  long j;
  511. #endif
  512.  
  513.     erase_mode = 0;
  514.     video_type = NORMAL;
  515.  
  516.     for (element_num = 0;
  517.          element_num < num_elements; element_num++)
  518.     {
  519.          srow = (*element_ptr[element_num]).start_row - rowOffset;
  520.  
  521. /*             if ( (srow > 0) && (srow <= SCREEN_HEIGHT+1) ) */
  522.            if ( (srow > 0) && (srow <= (*window_ptr).num_rows))
  523.         {
  524.         len = strlen((*element_ptr[element_num]).label);
  525.         scol = (*element_ptr[element_num]).start_col - colOffset;
  526.         put_chars((*window_ptr).wind_id,
  527.                (*element_ptr[element_num]).label, len,
  528.                srow, scol,
  529.                erase_mode, video_type);
  530.         }
  531. #if MARKLOAD
  532. sprintf (message,"   (load_stat) [%ld] at (%ld,%ld)",element_num, srow, scol);
  533.  MESS_display ("                                            ",0);
  534.  for (j=0; j<35; j++) MESS_display (message,0);
  535. #endif
  536.  
  537.     }
  538.  
  539. }  /* end WFL_load_menu */
  540.  
  541.  
  542.                            /*CodeRef-mark*/
  543.  
  544. long int WFL_read_menu (element_ptr, num_elements, window_ptr,
  545.             menu_choice, windowHead, highlight)
  546. struct  menu_element_struct       *element_ptr[];
  547. int                    num_elements;
  548. struct  window_struct          *window_ptr;
  549. int                   *menu_choice;
  550. int                           *windowHead;
  551. int                           highlight;
  552. /*
  553.  Modification, October 1988, Dan Grogan, to allow a
  554.  "DARK" menu, one without a highlight bar.
  555.  Argument highlight is a boolean, if true, then highlight ON.
  556.  If false, then highlight is OFF.
  557.  
  558.  Return value: filtered keyboard code of KB_ or KBM_ set.
  559. */
  560.                            /*CodeRef-mark*/
  561. {
  562.     int            element_num;
  563.     int            old_element;
  564.     int            num_rows;
  565.     int            num_cols;
  566.     char            value;
  567.     int            keyWas;
  568.  
  569.     int               winTop,  winBot, winHgt;
  570.     int               rowOffset, colOffset;
  571.     int            nScrolls, k;
  572.  
  573.     element_num = *menu_choice;
  574.  
  575.     winTop = *windowHead;
  576.     winHgt = (*window_ptr).num_rows;
  577.     winBot = winTop + winHgt -1;
  578.  
  579.     rowOffset = (*element_ptr[winTop]).start_row -1;
  580.     colOffset = 0;
  581. /***                   DEVELOPMENT NOTE:
  582.         colOffset should be 0 until horizontal scrolling implemented:
  583.         colOffset = (*element_ptr[element_num]).start_col -1;
  584. ***/
  585.  
  586.     num_cols = strlen((*element_ptr[element_num]).label);
  587.     num_rows = 1;
  588.  
  589.     if (highlight) highlight_on((*window_ptr).wind_id,
  590.              (*element_ptr[element_num]).start_row -rowOffset,
  591.              (*element_ptr[element_num]).start_col -colOffset,
  592.                num_rows, num_cols);
  593.  
  594.     keyWas = 0;
  595.  
  596. #if defined(vms)
  597.     set_cursor_mode (CURSOR_OFF);
  598. #endif
  599.     while     (  (keyWas != KB_CONTEXT_HELP)
  600.         && (keyWas != KBM_SELECT)
  601.         && (keyWas != KBM_BACK)
  602.         && (keyWas != KBM_HELP)
  603.         && (keyWas != KBM_LEFT)
  604.         && (keyWas != KBM_RIGHT)
  605.         && (keyWas != KBM_QUIT)
  606.         && (keyWas != KBM_EXIT) )
  607.         {
  608.  
  609.         place_cursor_abs((*window_ptr).wind_id,
  610.              (*element_ptr[element_num]).start_row -rowOffset,
  611.              (*element_ptr[element_num]).start_col -colOffset);
  612.  
  613. #ifdef vms
  614.         get_input(&value, &keyWas);
  615. #endif
  616. #if defined(unix)  | defined(__MSDOS__)
  617.         get_input ((*window_ptr).wind_id, &value, &keyWas);
  618. #endif
  619.  
  620. /*
  621. Have to use this because ALPHA U and D are used for paging
  622. */
  623.         if( value == KBM_PREVSCRN   ||
  624.             value == KBM_prevscrn   ||
  625.             value == KBM_NEXTSCRN   ||
  626.             value == KBM_nextscrn)
  627.             keyWas = value;
  628.  
  629.         WFL_begin_display_update (window_ptr);
  630.  
  631.         switch    (keyWas)
  632.             {
  633.             case KBM_LEFT:
  634.             case KBM_RIGHT:
  635.             case KBM_BACK:
  636.             case KBM_QUIT:
  637.             case KBM_EXIT:
  638.                  *menu_choice = element_num;
  639.                  break;
  640.  
  641.             case KB_CONTEXT_HELP:
  642.             case KBM_SELECT:
  643.             case KBM_HELP:
  644.                  *menu_choice = element_num;
  645.                  *windowHead = winTop;
  646.                  break;
  647.  
  648.             case KB_PAD7:
  649.             case KBM_PREVSCRN:
  650.             case KBM_prevscrn:
  651.             case KBM_UP:
  652.  
  653.  
  654.          if ( (keyWas == KBM_PREVSCRN) ||(keyWas == KBM_prevscrn) ||
  655.           (keyWas == KB_PAD7) )
  656.          nScrolls = (*window_ptr).num_rows -1;
  657.          else
  658.          nScrolls = 1;
  659.  
  660.     for (k=0; k<nScrolls; k++)
  661.         {
  662.  
  663.          old_element = element_num;
  664.  
  665.          if ( (keyWas == KBM_PREVSCRN) || (keyWas == KBM_prevscrn) ||
  666.           (keyWas == KB_PAD7) )
  667.                          /* no wrap on page up */
  668.         {
  669.         if (element_num > 0)
  670.             element_num --;
  671.         else
  672.             element_num = 0;
  673.         }
  674.          else
  675.         {
  676.         if (element_num > 0)
  677.             element_num --;
  678.         else
  679.             element_num = num_elements -1;
  680.         }
  681.  
  682.          if (highlight) highlight_off ( (*window_ptr).wind_id,
  683.                (*element_ptr[old_element]).start_row -rowOffset,
  684.                   1, 1,
  685.                  strlen((*element_ptr[old_element]).label) );
  686.  
  687.  
  688.          if (element_num < winTop)
  689.         {
  690.         winTop = element_num;
  691.         winBot = winTop + winHgt -1;
  692.  
  693.         WFL_erase_display (window_ptr);
  694.         rowOffset--;
  695.  
  696.         WFL_load_menu (element_ptr, num_elements, window_ptr,
  697.                     rowOffset, colOffset);
  698.         }
  699.  
  700.          else if (element_num > winBot)  /* wrap top-to-bot */
  701.         {
  702.         winBot = element_num;
  703.         winTop = winBot -winHgt +1;
  704.  
  705.         WFL_erase_display (window_ptr);
  706.         rowOffset = (*element_ptr[winTop]).start_row -1;
  707.  
  708.         WFL_load_menu (element_ptr, num_elements, window_ptr,
  709.                     rowOffset, colOffset);
  710.         }
  711.  
  712.          if (highlight) highlight_on  ( (*window_ptr).wind_id,
  713.                (*element_ptr[element_num]).start_row -rowOffset,
  714.                   1, 1,
  715.                  strlen((*element_ptr[element_num]).label) );
  716.  
  717.        }  /* end for k to nScrolls */
  718.  
  719.          break;
  720.  
  721.  
  722.             case KB_PAD4:
  723.             case KBM_NEXTSCRN:
  724.             case KBM_nextscrn:
  725.             case KBM_DOWN:
  726.  
  727.          if ( (keyWas == KBM_NEXTSCRN) || (keyWas == KBM_nextscrn) ||
  728.           (keyWas == KB_PAD4) )
  729.          nScrolls = (*window_ptr).num_rows -1;
  730.          else
  731.          nScrolls = 1;
  732.  
  733.     for (k=0; k<nScrolls; k++)
  734.         {
  735.  
  736.          old_element = element_num;
  737.  
  738.          if ( (keyWas == KBM_NEXTSCRN) || (keyWas == KBM_nextscrn) ||
  739.           (keyWas == KB_PAD4) )
  740.                          /* no wrap on page down */
  741.         {
  742.         if (element_num < num_elements -1)
  743.             element_num++;
  744.         else
  745.             element_num = num_elements -1;
  746.         }
  747.          else
  748.                 {
  749.                 if (element_num < num_elements-1)
  750.             element_num++;
  751.                 else
  752.                     element_num = 0;
  753.                 }
  754.                               
  755.              if (highlight) highlight_off ( (*window_ptr).wind_id, 
  756.                            (*element_ptr[old_element]).start_row -rowOffset,
  757.                               1, 1,
  758.                  strlen((*element_ptr[old_element]).label) );
  759.  
  760.  
  761.          if (element_num < winTop)   /* wrap bot-to-top */
  762.         {
  763.         winTop = element_num;
  764.         winBot = winTop + winHgt -1;
  765.  
  766.         WFL_erase_display (window_ptr);
  767.         rowOffset = (*element_ptr[winTop]).start_row -1;
  768.  
  769.         WFL_load_menu (element_ptr, num_elements, window_ptr,
  770.                     rowOffset, colOffset);
  771.         }
  772.  
  773.          if (element_num > winBot)
  774.         {
  775.         winBot = element_num;
  776.         winTop = winBot -winHgt +1;
  777.  
  778.         WFL_erase_display (window_ptr);
  779.         rowOffset++;
  780.  
  781.         WFL_load_menu (element_ptr, num_elements, window_ptr,
  782.                     rowOffset, colOffset);
  783.         }
  784.  
  785.          if (highlight) highlight_on  ( (*window_ptr).wind_id,
  786.                (*element_ptr[element_num]).start_row -rowOffset,
  787.                   1, 1,
  788.                  strlen((*element_ptr[element_num]).label) );
  789.  
  790.        }  /* end for k to nScrolls */
  791.  
  792.           break;
  793.  
  794.             case REDRAW:
  795.                  redraw_screen();
  796.                  break;
  797.  
  798.         }  /* end switch(keyWas) */
  799. #if !defined(vms)
  800.         WFL_end_display_update_nobox(window_ptr);
  801. #else
  802.         WFL_end_display_update(window_ptr);
  803. #endif
  804.         }   /* end while (keyWas != some exit condition) */
  805. #if defined(vms)
  806.      set_cursor_mode (CURSOR_ON);
  807. #endif
  808.      return (keyWas);
  809.  
  810. }   /* end WFL_read_menu  */
  811.  
  812.  
  813.                            /*CodeRef-mark*/
  814.  
  815.  
  816.   /*
  817.    *  Dynamic menu functions
  818.    */
  819.  
  820.  
  821.                            /*CodeRef-mark*/
  822.  
  823.                            /*CodeRef-mark*/
  824.  
  825.  
  826.  
  827.  
  828.                            /*CodeRef-mark*/
  829.  
  830. long int WFL_new_dyna_window (window, banner)
  831. struct window_struct  **window;
  832. char           *banner;
  833.   /*
  834.    *  Allocate memory for one transient window and copy the
  835.    *  banner string into the label field of the window.
  836.    *  No protection against too-long banner string.
  837.    *  Return value: 0 = successful allocation, -1 = failure.
  838.    */
  839.                            /*CodeRef-mark*/
  840. {
  841.   *window = ((struct window_struct *) malloc(sizeof(struct window_struct)));
  842.   if (*window == NULL)
  843.      {
  844.      printf ("\n (new_dyna_window): NULL pointer from allocate dyna window.");
  845.      return (-1L);
  846.      }
  847.   strcpy ( (**window).label, banner);
  848.  
  849. #if DEBUG1
  850.   printf ("\n (new_dyna_window): (**window).label = %s", (**window).label);
  851. #endif
  852.  
  853.   return (0L);
  854. }   /* end WFL_new_dyna_window */
  855.  
  856.  
  857.  
  858.                            /*CodeRef-mark*/
  859.  
  860. void WFL_delete_dyna_window (window)
  861. struct window_struct *window;
  862.  
  863. {
  864.     free ((char *) window);
  865. }    /*  end WFL_delete_dyna_window */
  866.  
  867.  
  868.  
  869.  
  870. void WFL_set_dyna_window (startRow, startCol, maxRows, element_list,
  871.             window)
  872. int             startRow;
  873. int             startCol;
  874. int             maxRows;
  875. char             *element_list[];
  876. struct window_struct     *window;
  877.   /*
  878.    *  Initializes a transient window for displaying the element_list[]:
  879.    *     Set window.start_row equal to startRow.
  880.    *     Set window.start_col equal to startCol.
  881.    *     Set window.num_cols  equal to the length of the
  882.    *            longest string in the list, limited by SCREEN_WIDTH.
  883.    *     Set window.num_rows  equal to the number of items
  884.    *            in the list, limited by maxRows.
  885.    *     maxCols is not in use -- later to be a limit for num_cols.
  886.    *
  887.    *  If the resultant window would not show completely on the video
  888.    *  screen, window.start_row and window.start_col will be adjusted
  889.    *  so that as much of the window as possible is displayed.
  890.    *  That is, the window's upper-left corner gets moved toward the
  891.    *  position (1,1).
  892.    */
  893.                            /*CodeRef-mark*/
  894. {
  895.   (*window).num_rows = string_count (element_list);
  896.   if ((*window).num_rows > maxRows)
  897.       (*window).num_rows = maxRows;
  898.  
  899.   (*window).num_cols = longest_string (element_list);
  900.   if ( strlen((*window).label)  > (*window).num_cols )
  901.      (*window).num_cols =  strlen((*window).label);
  902.  
  903.   /*
  904.    *  adjust start row and column if necessary --
  905.    *  make it stay in the screen, if possible.
  906.    */
  907.   if ( (startRow + (*window).num_rows) > SCREEN_HEIGHT)
  908.     (*window).start_row = SCREEN_HEIGHT -(*window).num_rows;
  909.   else
  910.     (*window).start_row = startRow;
  911.  
  912.   if ( (startCol + (*window).num_cols) > SCREEN_WIDTH)
  913.     (*window).start_col = SCREEN_WIDTH -(*window).num_cols;
  914.   else
  915.     (*window).start_col = startCol;
  916.  
  917.   if ( (*window).start_row < 2L) (*window).start_row = 2L;
  918.   if ( (*window).start_col < 2L) (*window).start_col = 2L;
  919.  
  920.   WFL_create_window (window);
  921.  
  922. } /* end WFL_set_dyna_window */
  923.  
  924.  
  925.  
  926.                            /*CodeRef-mark*/
  927.  
  928. long int WFL_new_dyna_elem_list (menu_element_ptr, element_list)
  929. struct menu_element_struct   *menu_element_ptr[];
  930. char                         *element_list[];
  931. /*
  932.  *   This function creates a menu list form a text list.
  933.  */
  934.                            /*CodeRef-mark*/
  935. {
  936.      int num_elements;
  937.      int k;
  938.  
  939.   num_elements = string_count (element_list);
  940.  
  941.   for (k=0; k<num_elements; k++)
  942.      {
  943.  
  944. #if DEBUG1
  945.      printf ("\n (new_elem_list): menu_element_ptr[%ld] = %ld",
  946.           k, menu_element_ptr[k]);
  947. #endif
  948.  
  949.      menu_element_ptr[k] = ((struct menu_element_struct *)
  950.          malloc (sizeof(struct menu_element_struct)));
  951.      if (menu_element_ptr[k] == NULL)
  952.     {
  953.     printf ("\n WFL: NULL pointer trying to allocate menu element.");
  954.     return (-1L);
  955.     }
  956.  
  957.      (*menu_element_ptr[k]).start_row = k +1;
  958.      (*menu_element_ptr[k]).start_col = 1;
  959.      strcpy ( (*menu_element_ptr[k]).label, element_list[k]);
  960.  
  961.      } /* end k-loop */
  962.  
  963.   return (0L);
  964. }   /* end WFL_new_dyna_elem_list */
  965.  
  966.  
  967.                            /*CodeRef-mark*/
  968.  
  969. struct menu_element_struct **WFL_new_dyna_menu (element_list)
  970. char     *element_list[];
  971.   /*  This function does the following:
  972.    *  1. Makes a menu selection list from the element_list.
  973.    *  2. Allocates memory for one menu pointer-list and
  974.    *     memory for all the elements pointed-to by the list.
  975.    *     element_list[] is a WFL 'null-terminated array of strings'.
  976.    *  3. Sets row and col for each element.
  977.    *  4. Loads the label for each element.
  978.    *
  979.    *  Return value:
  980.    *    a pointer to the array of pointers, or for failure, NULL.
  981.    *  This function is used in building dynamic menus.
  982.    *  You must call WFL_delete_dyna_menu() to assure proper
  983.    *  deallocation of the dynamic menu.
  984.    */
  985.                            /*CodeRef-mark*/
  986. {
  987.      int num_elements;
  988.      /*int k;*/
  989.  
  990.      struct menu_element_struct **ptr;
  991.  
  992.   num_elements = string_count (element_list);
  993.  
  994.   ptr = ((struct menu_element_struct **)
  995.        calloc(num_elements, sizeof(struct menu_element_struct * )));
  996.   if (ptr == NULL) return NULL;
  997.  
  998.   WFL_new_dyna_elem_list (ptr, element_list);
  999.   return ptr;
  1000.  
  1001. }   /* end WFL_new_dyna_menu */
  1002.  
  1003.  
  1004. void WFL_delete_dyna_menu (ptr, element_list)
  1005. struct menu_element_struct   **ptr;
  1006. char                          *element_list[];
  1007.   /*
  1008.    *  This function dellocates memory for one menu pointer-list and
  1009.    *  memory for all the elements pointed-to by the list.
  1010.    *  A return value of 0 indicates success, non-zero is failure.
  1011.    *  Call it to deallocate memory after using WFL_new_dyna_menu()
  1012.    *  The parameter "ptr" is a pointer-pointer which has been set by
  1013.    *  WFL_new_dyna_menu() and the element_list[] is the same one used
  1014.    *  when the new menu was created.
  1015.    */
  1016.                            /*CodeRef-mark*/
  1017. {
  1018.      int num_elements;
  1019.      int k;
  1020.  
  1021.      /*int status;*/
  1022.  
  1023.   num_elements = string_count (element_list);
  1024.  
  1025.   for (k=0; k<num_elements; k++)
  1026.       {
  1027.       free ( (struct menu_element_struct *) ptr[k]);
  1028.       }
  1029. /*  free ((struct menu_struct_type **) ptr); can't find this structure */
  1030.  free ((struct menu_element_struct**) ptr);
  1031. }   /* end WFL_delete_dyna_menu */
  1032.  
  1033.  
  1034. int WFL_popup_menu (startRow, startCol, maxRows,
  1035.          banner, element_list, user_selection, menu_id, highlight)
  1036. int                    startRow;
  1037. int                startCol;
  1038. int                    maxRows;
  1039. char                  *banner;
  1040. char                  *element_list[];
  1041. long int          *user_selection;
  1042. int                 menu_id;
  1043. int               highlight;
  1044.   /*
  1045.    *
  1046.    *   WFL_popup_menu pops up a menu on-the-fly and returns the index
  1047.    *   of the element selected by the user in the variable user_selection.
  1048.    *
  1049.    *   startRow and startCol position the upper-left corner of the menu
  1050.    *   window on the screen.
  1051.    *
  1052.    *   maxRows limits the height of the window -- if there are fewer
  1053.    *   than maxRows items in element_list[], the window will be sized
  1054.    *   to exactly hold the list.
  1055.    *   maxCols is not being used yet -- pass any value.
  1056.    *
  1057.    *   banner is the menu-window label string.
  1058.    *
  1059.    *   element_list is a WFL 'null-terminated array of strings'.
  1060.    *
  1061.    *   WFL_popup_menu creates a transient window and creates a menu selection
  1062.    *   list from the element_list[] and
  1063.    *   initializes them both and then displays the menu, waiting for
  1064.    *   the user to make a selection.
  1065.    *   After the selection, the window is erased and deleted and
  1066.    *   transient memory is deallocated.
  1067.    *
  1068.    * ---
  1069.  
  1070. ---   Mods, October 1988, Dan Grogan
  1071.  
  1072.       Menus may now remain open (and on-screen) while the user is
  1073.       active in another menu or form  because of the menu_id argument.
  1074.       The menu_id is an integer constant and the key to static state
  1075.       variables that record the current state of an open menu.
  1076.  
  1077.       Other than the "transient-menu", an opened menu will remain open
  1078.       until the user presses the KBM_QUIT key.  For instance, if the
  1079.       user is in menu 1 (menu_id=1) and SELECTs item 5, controls
  1080.       returns to the caller with the state of menu 1 saved, and menu 1
  1081.       still on-screen.  When WFL_popup_menu is called again for menu
  1082.       1, its status is still open and the selection bar returns to
  1083.       where it was last, at item 5.  Only when the user QUITs menu 1
  1084.       will menu 1 be removed from the screen and deallocated.  And its
  1085.       recorded state will be marked as closed.
  1086.       The TRANSIENT_MENU (menu_id=0) is a special case and never remains
  1087.       open; all returns to the caller close the menu.
  1088.  
  1089.       The highlight argument now allows a "dark" menu, one
  1090.       without highlight bar -- dark menu with highlight FALSE;
  1091.       regular menu with highlight = TRUE.  The dark menu may be used
  1092.       as a scrollable informnation box.
  1093.    *
  1094.    *   Return value:  filtered keyboard code from WFL_read_menu().
  1095.    */
  1096.                            /*CodeRef-mark*/
  1097. {
  1098.     /*char message[200];*/
  1099.     int real_row, real_col;
  1100.  
  1101.      /*int                   stat;*/
  1102.      int                   keyWas;
  1103.      int           num_elements;
  1104.  
  1105. /*
  1106.  *  These values are now being saved for returning the state of an
  1107.  *  menu left open....
  1108.  */
  1109.  
  1110.      static struct menu_element_struct  **menu_element_ptr[MAX_MENUS]=
  1111. {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
  1112.  
  1113.      static struct window_struct      *window_ptr[MAX_MENUS]=
  1114. {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
  1115.  
  1116.      static int  menuChoice[MAX_MENUS] =
  1117. {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
  1118.  
  1119.      static int windowHead[MAX_MENUS] =
  1120. {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
  1121.  
  1122.  
  1123. if ( (window_ptr[menu_id] == 0) ||  /* the requested menu is not open */
  1124.      (menu_id == TRANSIENT) )
  1125.    {
  1126.  
  1127.      WFL_new_dyna_window (&window_ptr[menu_id], banner);
  1128.  
  1129.      WFL_set_dyna_window (startRow, startCol, maxRows,
  1130.               element_list, window_ptr[menu_id] );
  1131.  
  1132.         /* Make a menu selection list from the element_list */
  1133.      menu_element_ptr[menu_id] = WFL_new_dyna_menu (element_list);
  1134.  
  1135.      WFL_draw_window (window_ptr[menu_id]);
  1136.  
  1137.      WFL_load_menu (menu_element_ptr[menu_id], string_count(element_list),
  1138.             window_ptr[menu_id], windowHead[menu_id], 0);
  1139.    }
  1140.  
  1141.      num_elements = string_count(element_list);
  1142.  
  1143.      do  /* until user key is acceptable */
  1144.        {
  1145.        keyWas = WFL_read_menu (
  1146.                    menu_element_ptr[menu_id],
  1147.                    num_elements,
  1148.                    window_ptr[menu_id],
  1149.                    &menuChoice[menu_id],
  1150.                    &windowHead[menu_id],
  1151.                 highlight );
  1152.        }
  1153.        while (     (keyWas != KB_CONTEXT_HELP) &&
  1154.         (keyWas != KBM_SELECT) &&
  1155.         (keyWas != KBM_LEFT)   &&
  1156.         (keyWas != KBM_RIGHT)  &&
  1157.         (keyWas != KBM_QUIT)   &&
  1158.         (keyWas != KBM_HELP)   &&
  1159.         (keyWas != KBM_EXIT) );
  1160.  
  1161.      *user_selection = menuChoice[menu_id];
  1162.  
  1163. /*
  1164.  *   If the key was EXIT the current menu or
  1165.  *       if the menu is the transient menu (id = 0), the menu will be closed.
  1166.  *   If the key was SELECT, HELP, QUIT, or other, the menu will be left
  1167.  *      open and may be re-entered with the state the same.
  1168.  */
  1169.  
  1170.      if ( (keyWas == KBM_EXIT) ||
  1171.       (menu_id == TRANSIENT) )
  1172.     {
  1173.       /* get rid of the current window and menu */
  1174.  
  1175.     WFL_erase_window (window_ptr[menu_id]);
  1176.  
  1177.     WFL_delete_dyna_window (window_ptr[menu_id]);
  1178.  
  1179.     WFL_delete_dyna_menu (menu_element_ptr[menu_id],
  1180.                      element_list);
  1181.     menuChoice[menu_id] = 0;
  1182.     windowHead[menu_id] = 0;
  1183.     window_ptr[menu_id] = 0;
  1184.     menu_element_ptr[menu_id] = 0;
  1185.  
  1186.     }  /* end of get rid of  window */
  1187.      else
  1188.     {
  1189.     /* remember the position of the select bar -- (keep the menu open) */
  1190.  
  1191.     real_row = window_ptr[menu_id]->start_row;
  1192.     real_col = window_ptr[menu_id]->start_col;
  1193.  
  1194.  
  1195.     menu_bar_last_at_row (real_row);
  1196.     menu_bar_last_at_col (real_col);
  1197.  
  1198.     }  /* end of keep menu open */
  1199.  
  1200.      return (keyWas);
  1201.  
  1202. }  /* end WFL_popup_menu */
  1203.  
  1204.  
  1205.                                                    /*CodeRef-mark*/
  1206.  
  1207.  
  1208.  
  1209.  
  1210.                                                    /*CodeRef-mark*/
  1211.   /* 
  1212.    *   Form functions
  1213.    */
  1214.  
  1215.  
  1216.                                                    /*CodeRef-mark*/
  1217.  
  1218.                                                    /*CodeRef-mark*/
  1219.  
  1220. void WFL_load_form (element_ptr, num_elements, window_ptr)
  1221. struct  form_element_struct  *element_ptr[];
  1222. int              num_elements;
  1223. struct  window_struct        *window_ptr;
  1224. /*
  1225.  *  Initialize the form.  After window is drawn this function is
  1226.  *  called to load each element of a form into the window.
  1227.  */
  1228.                            /*CodeRef-mark*/
  1229. {
  1230.     int            element_num;
  1231.     int            erase_mode;
  1232.     int            video_type;
  1233.     int            len;
  1234.  
  1235.     erase_mode = 0;
  1236.     video_type = NORMAL;
  1237.     for (element_num = 0; element_num < num_elements; ++element_num)
  1238.     {
  1239.  
  1240.          len = strlen((*element_ptr[element_num]).label);
  1241.          put_chars((*window_ptr).wind_id,
  1242.             (*element_ptr[element_num]).label, len,
  1243.             (*element_ptr[element_num]).start_row,
  1244.             (*element_ptr[element_num]).start_col,
  1245.              erase_mode, video_type);
  1246.     }
  1247.  
  1248. }  /* end WFL_load_form  */
  1249.  
  1250.  
  1251.                            /*CodeRef-mark*/
  1252.  
  1253. long int WFL_rove_form (keyboard_code, current_element, lo, hi, increment)
  1254. int keyboard_code;
  1255. int *current_element;
  1256. int lo;   /* wrap around at elements lo <--> hi */
  1257. int hi;
  1258. int increment;
  1259.   /*
  1260.    *     Mods:  rework so that up and down arrows can be used to
  1261.      scroll up and down in regular 2-dimensionally arrayed form.
  1262.      The lo and hi indexes to the list must now be given and
  1263.      the increment, which is the length of one row, must be
  1264.      provided.
  1265.      For unstructured forms, use an increment of 1 (a zero or
  1266.      negative value will be over-ridden to 1).
  1267.  
  1268.    *     Function updates the current_element index (i-1, i+0, or i+1)
  1269.    *     for roving the elements in a form.
  1270.    *     Input is a filtered keyboard_code (e.g. return code
  1271.    *     from field_input()).
  1272.    *     Output is the updated current_element index.
  1273.    *
  1274.    *     Keyboard codes KBF_UP and KBF_PREVFIELD decrement;
  1275.    *     Keyboard codes KBF_DOWN and KBF_NEXTFIELD increment;
  1276.    *     Others leave current_element unchanged.
  1277.    *
  1278.    *     Return value: If keyboard_code is the KBF_EXIT signal, then
  1279.    *     WFL_rove_form returns TRUE, meaning done;
  1280.    *              else returns FALSE, not done with a form.
  1281.    */
  1282.                            /*CodeRef-mark*/
  1283. {
  1284.      int form_done;
  1285.      int row, col;
  1286.  
  1287.      form_done = FALSE;
  1288.  
  1289.      if (increment < 1) increment = 1;
  1290.  
  1291.      if ((keyboard_code == KBF_NEXTFIELD)  ||
  1292.      (keyboard_code == KBF_PREVFIELD) )
  1293.     increment = 1;
  1294.  
  1295.      switch (keyboard_code)
  1296.        {
  1297.        case KBF_DOWN:
  1298.        case KBF_NEXTFIELD:
  1299.                 *current_element += increment;
  1300.                 if ( *current_element > hi)
  1301.                 {
  1302.                 row = 0;
  1303.                 col = (*current_element -lo) % increment;
  1304.                 *current_element = lo +col;
  1305.                 }
  1306.                  break;
  1307.  
  1308.        case KBF_UP:
  1309.        case KBF_PREVFIELD:
  1310.                 *current_element -= increment;     
  1311.                      if ( *current_element < lo) 
  1312.                 {
  1313.                     *current_element += increment;     
  1314.                 row = (hi -lo) / increment;
  1315.                 col = (*current_element -lo) % increment;
  1316.                 *current_element = (row * increment) +col;
  1317.                          if ( *current_element > hi) 
  1318.                    *current_element -= increment;
  1319.                 }
  1320.                  break;
  1321.  
  1322.  
  1323.        case KBF_EXIT:        form_done = TRUE;         break;
  1324.        }
  1325.  
  1326. /******* OLDER FORMULA (THAT DOESN'T WORK PROPERLY) ****
  1327.      switch (keyboard_code) 
  1328.        {
  1329.        case KBF_DOWN:       
  1330.        case KBF_NEXTFIELD:   
  1331.                  if (*current_element == hi)
  1332.                      (*current_element) = lo;
  1333.                  else
  1334.                 {
  1335.                      *current_element += increment;     
  1336.                      if ( *current_element > hi) 
  1337.                      *current_element = lo + 
  1338.                                (*current_element -hi);
  1339.                 }
  1340.                  break;
  1341.  
  1342.        case KBF_UP:
  1343.        case KBF_PREVFIELD:   
  1344.                  if (*current_element == lo)
  1345.                      (*current_element) = hi;
  1346.                  else
  1347.                 {
  1348.                      *current_element -= increment;     
  1349.                      if ( *current_element < lo) 
  1350.                      *current_element = hi - 
  1351.                                (lo - *current_element);
  1352.                 }
  1353.                  break;
  1354.  
  1355.        case KBF_EXIT:        form_done = TRUE;         break;
  1356.        }
  1357. *******************  END OF OLDER FORMULA *****/
  1358.  
  1359.      return (form_done);
  1360.  
  1361. }  /* end WFL_rove_form */
  1362.  
  1363.  
  1364.                            /*CodeRef-mark*/
  1365.  
  1366. void WFL_generic_form (window_ptr, element_ptr, label, data_len)
  1367. struct  window_struct          *window_ptr;
  1368. struct  form_element_struct      *element_ptr[];
  1369. char                label[];
  1370. int                data_len;
  1371. /*
  1372.  *  Create a form for a single element input.  Used in conjuction
  1373.  *  with windows to create a popup box for retrieving answer to
  1374.  *  a single question.
  1375.  */
  1376.                            /*CodeRef-mark*/
  1377. {
  1378.     int            element_num;
  1379.     int            erase_mode;
  1380.     int            video_type;
  1381.     int            len;
  1382.  
  1383.     erase_mode = 0;
  1384.     video_type = NORMAL;  /* changed from _ONE (BOLD) */
  1385.     element_num = 0;
  1386.  
  1387.     len = strlen(label);
  1388.     /*
  1389.     printf("label,len,row,col %s %d %d %d %d\n", label,len,
  1390.     (*element_ptr[element_num]).start_row,
  1391.     (*element_ptr[element_num]).start_col,(*window_ptr).wind_id);
  1392.     */
  1393.     put_chars((*window_ptr).wind_id,
  1394.             label, len,
  1395.             (*element_ptr[element_num]).start_row,
  1396.             (*element_ptr[element_num]).start_col,
  1397.             erase_mode, video_type);
  1398.     (*element_ptr[element_num]).length_label = len;
  1399.     (*element_ptr[element_num]).length_field = data_len;
  1400.  
  1401. }  /*  end WFL_generic_form  */
  1402.  
  1403.  
  1404.                            /*CodeRef-mark*/
  1405.  
  1406. void WFL_display_form_data (window_ptr, element_ptr, data, data_type,
  1407.                 element_num, video_type)
  1408. struct  window_struct          *window_ptr;
  1409. struct  form_element_struct      *element_ptr[];
  1410. int                *data;
  1411. int                data_type;
  1412. int                element_num;
  1413. int                video_type;
  1414. /*
  1415.  *  Display form data passed by reference in "data".  Uses "data_type" to
  1416.  *  determine how to display and "element_num" to determine the
  1417.  *  location.
  1418.  */
  1419.                            /*CodeRef-mark*/
  1420. {
  1421.     char        *string_data;
  1422.     int        field_len;
  1423.     int        erase_mode;
  1424.     int        start_col;
  1425.     int        len;
  1426.     int        i;
  1427.     erase_mode = 0;
  1428.  
  1429. /* Determine space required for string to display data. */
  1430.  
  1431.     string_data = (char *)
  1432.             malloc((*element_ptr[element_num-1]).length_field);
  1433.  
  1434. /* Determine location to put data based on size of element label */
  1435.  
  1436.     field_len = (*element_ptr[element_num-1]).length_field;
  1437.     start_col = (*element_ptr[element_num-1]).start_col +
  1438.         (*element_ptr[element_num-1]).length_label ;
  1439.  
  1440. /* Convert data in string based on data_type.  If string just copy. */
  1441.  
  1442.     fieldValToString (data, data_type, string_data, field_len);
  1443.  
  1444. /********
  1445. ***************/
  1446.  
  1447. /********
  1448.     switch (data_type)
  1449.        {
  1450.         case DT_STRING:
  1451.             strncpy (string_data, data, field_len);
  1452.             break;
  1453.         case DT_LONGINT:
  1454.             sprintf (string_data, "%ld",
  1455.                 *data);
  1456.             break;
  1457.         case DT_FLOAT:
  1458.             sprintf (string_data, "%f",
  1459.                 *data);
  1460.             break;
  1461.         default:
  1462.             break;
  1463.        }
  1464. ***************/
  1465.  
  1466.  
  1467. /* Left justify string and display data into field area.  */
  1468.  
  1469.     left_justify(string_data, field_len);
  1470.     len = strlen(string_data);
  1471.     for (i = len; i < field_len; i++)
  1472.          string_data[i] = ' ';
  1473.     put_chars ((*window_ptr).wind_id, string_data, field_len,
  1474.             (*element_ptr[element_num-1]).start_row,
  1475.             start_col, erase_mode, video_type);
  1476.  
  1477.     free(string_data);
  1478.  
  1479. }  /*  end WFL_display_form_data  */
  1480.  
  1481.  
  1482.                            /*CodeRef-mark*/
  1483.  
  1484. void WFL_read_element (window_ptr, element_ptr, data,
  1485.             data_type, element_num, rcode)
  1486. struct  window_struct          *window_ptr;
  1487. struct  form_element_struct      *element_ptr[];
  1488. int                *data;
  1489. int                data_type;
  1490. int                element_num;
  1491. int                *rcode;
  1492. /*
  1493.  *  Read data for form element defined by "element_num".  All data
  1494.  *  is initially read in as a string and then converted based on
  1495.  *  "data_type".  If data is going to be retrieved through the
  1496.  *  use of the 'callback' feature, then it should be defined as
  1497.  *  when the form is initialized.  Data is returned in "data".
  1498.  */
  1499.                            /*CodeRef-mark*/
  1500. {
  1501.     char        *string_data;
  1502.     int        field_len;
  1503.     int        start_col;
  1504.     int        status;
  1505.  
  1506. /*  Check the type of element and take appropriate action.  */
  1507.  
  1508.     if ((*element_ptr[element_num-1]).type == FORM_CALLBACK)
  1509.        {
  1510.        WFL_read_callback((CFP) (*element_ptr[element_num-1]).callback,
  1511.                  (int *) (*element_ptr[element_num-1]).popup,
  1512.          data, rcode);
  1513.        }
  1514.     else if((*element_ptr[element_num-1]).type == MENU_CALLBACK)
  1515.          {
  1516.          WFL_read_callback(
  1517.          (CFP)(*element_ptr[element_num-1]).callback,
  1518.          (int *)(*element_ptr[element_num-1]).popup,
  1519.              data, rcode);
  1520.  
  1521.  
  1522. /* Re-display data based on popup menu selection.  */
  1523.  
  1524.          WFL_display_form_data (window_ptr, element_ptr,
  1525.              data, data_type, element_num, BOLD);
  1526.          }
  1527.  
  1528.          /*
  1529.           *  DUMMY_FORM allows for entries which are for
  1530.           *  info only, no input field
  1531.           */
  1532.     else if((*element_ptr[element_num-1]).type != DUMMY_FORM)
  1533.  
  1534.     {
  1535.  
  1536. /*  Reverse the data display to show user the current element.  */
  1537.  
  1538.          WFL_display_form_data (window_ptr, element_ptr,
  1539.              data, data_type, element_num, REVERSE);
  1540.  
  1541. /*  Create space required for string used to retrieve the data.  */
  1542.  
  1543.     string_data = (char *)
  1544.             malloc((*element_ptr[element_num-1]).length_field);
  1545.  
  1546. /*  Determine location of the data.  */
  1547.  
  1548.     field_len = (*element_ptr[element_num-1]).length_field;
  1549.     start_col = (*element_ptr[element_num-1]).start_col +
  1550.         (*element_ptr[element_num-1]).length_label ;
  1551.  
  1552. /*  Convert the current value of data to string form.  */
  1553.  
  1554.     fieldValToString (data, data_type, string_data, field_len);
  1555.  
  1556. /********
  1557. ***************/
  1558.  
  1559. /********
  1560.     switch (data_type)
  1561.        {
  1562.         case DT_STRING:
  1563.             strncpy (string_data, data, field_len);
  1564.             break;
  1565.         case DT_LONGINT:
  1566.             sprintf (string_data, "%ld",
  1567.                 *data);
  1568.             break;
  1569.         case DT_FLOAT:
  1570.             sprintf (string_data, "%f",
  1571.                 *data);
  1572.             break;
  1573.        }
  1574. ***************/
  1575.  
  1576.     left_justify(string_data, field_len);
  1577.  
  1578.     status = FALSE;
  1579.  
  1580. /*  While input is not valid get input from the user for the element.  This
  1581.     loop is put in to keep the user from entering bad data.  (e.g. entering
  1582.     a character when a numeric value is required.)  */
  1583.  
  1584.     while (!status)
  1585.        {
  1586.        input_field ((*window_ptr).wind_id, string_data,
  1587.             (*element_ptr[element_num-1]).start_row,
  1588.             start_col, field_len, rcode);
  1589.  
  1590. /* Try to convert string back to data of original type.  */
  1591.  
  1592.     status = stringToFieldVal(data, data_type, string_data, field_len);
  1593.  
  1594. /********
  1595. ***************/
  1596.  
  1597. /********
  1598.        switch (data_type)
  1599.           {
  1600.         case DT_STRING:
  1601.             strncpy (data, string_data, field_len);
  1602.             status = TRUE;
  1603.             break;
  1604.         case DT_LONGINT:
  1605.             status = sscanf (string_data, "%ld", data);
  1606.             break;
  1607.         case DT_FLOAT:
  1608.             status = sscanf (string_data, "%f", data);
  1609.             break;
  1610.  
  1611.           }
  1612. ***************/
  1613.  
  1614.        }
  1615.  
  1616. /*  Re-display data in normal mode when completed.  */
  1617.  
  1618.     WFL_display_form_data (window_ptr, element_ptr,
  1619.             data, data_type, element_num, BOLD);
  1620.  
  1621.     free(string_data);
  1622.  
  1623.     }
  1624.  
  1625. }  /*  end WFL_read_element  */
  1626.  
  1627.  
  1628.                            /*CodeRef-mark*/
  1629.   /*
  1630.    *   Functions for integrating forms and menus.
  1631.    */
  1632.  
  1633.  
  1634.                            /*CodeRef-mark*/
  1635.  
  1636.                            /*CodeRef-mark*/
  1637.  
  1638. void WFL_create_popup (c)
  1639. struct    window_struct         **c;
  1640. /*
  1641.  *  Create space required for a popup window structure.
  1642.  */
  1643.                            /*CodeRef-mark*/
  1644. {
  1645.     *c = (struct window_struct *) malloc(sizeof(struct window_struct));
  1646.  
  1647. }  /*  end WFL_create_popup  */
  1648.  
  1649.  
  1650.                            /*CodeRef-mark*/
  1651.  
  1652. void WFL_set_popup_window ( window_ptr, parent_ptr, element_ptr, element_num,
  1653.                 num_elements)
  1654. struct    window_struct             *window_ptr;
  1655. struct    window_struct             *parent_ptr;
  1656. struct  form_element_struct      *element_ptr[];
  1657. int                element_num;
  1658. int                num_elements;
  1659. /*
  1660.  *  Use information from the element of the parent form to determine
  1661.  *  the size and location of the popup window.  This function is used
  1662.  *  in conjuction with the other 'callback' functions to create a
  1663.  *  popup window for input of a form element.  All the information from
  1664.  *  the parent form is inherited in this window.
  1665.  */
  1666.                            /*CodeRef-mark*/
  1667. {
  1668.     int    field_len;
  1669.     int     start_col;
  1670.     int    start_row;
  1671.  
  1672. /* Determin size and location from the parent element. */
  1673.  
  1674.     field_len = (*element_ptr[element_num-1]).length_field;
  1675.     start_col = (*element_ptr[element_num-1]).start_col +
  1676.         (*element_ptr[element_num-1]).length_label +
  1677.         (*parent_ptr).start_col;
  1678.     start_row = (*element_ptr[element_num-1]).start_row +
  1679.         (*parent_ptr).start_row;
  1680.  
  1681.     (*window_ptr).start_row = start_row;
  1682.     (*window_ptr).start_col = start_col;
  1683.     (*window_ptr).num_cols = field_len;
  1684.     (*window_ptr).num_rows = num_elements;
  1685.     (*window_ptr).label[0] = '\0';
  1686.  
  1687. }  /*  end WFL_set_popup_window  */
  1688.  
  1689.  
  1690.                            /*CodeRef-mark*/
  1691.  
  1692. void WFL_popup_connect (element_ptr, element_num, context_ptr, callback_ptr)
  1693. struct  form_element_struct      *element_ptr[];
  1694. int            element_num;
  1695. int            *context_ptr;
  1696. CFP            callback_ptr;
  1697. /*
  1698.  *  Connect the window structure pointer and the pointer to the function
  1699.  *  to be called, when the element is selected, to the parent element.
  1700.  *  This should be called when the popup window is initialized and requires
  1701.  *  the parent element pointer.
  1702.  */
  1703.                            /*CodeRef-mark*/
  1704. {
  1705.     (*element_ptr[element_num-1]).popup = (char *) context_ptr;
  1706.     (*element_ptr[element_num-1]).callback = (CFP) callback_ptr;
  1707.  
  1708. }  /*  end WFL_popup_connect  */
  1709.  
  1710.  
  1711.                            /*CodeRef-mark*/
  1712.  
  1713. void WFL_get_popup_pointer (element_ptr, element_num, context_ptr)
  1714. struct  form_element_struct    *element_ptr[];
  1715. int                element_num;
  1716. int                **context_ptr;
  1717. /*
  1718.  *  Returns the pointer to the popup window structure contained
  1719.  *  in the structure of the parent form element.
  1720.  */
  1721.                            /*CodeRef-mark*/
  1722. {
  1723.     *context_ptr = (int *) (*element_ptr[element_num-1]).popup;
  1724.  
  1725. }  /*  end WFL_get_popup_pointer  */
  1726.  
  1727.  
  1728.  
  1729.                        /*CodeRef-mark*/
  1730.  
  1731. void WFL_read_callback(callback, popup, data, rcode)
  1732. CFP    callback;
  1733. int    *popup;
  1734. int    *data;
  1735. int     *rcode;
  1736. /*
  1737.  *  Call back application with appropriate function to retrieve the
  1738.  *  data needed for the parent element.  This function is called as
  1739.  *  subordinate function of WFL package.  The application should
  1740.  *  never call this function.
  1741.  */
  1742.                            /*CodeRef-mark*/
  1743. {
  1744.     (*callback) (popup, data, rcode);
  1745.  
  1746. }  /* end WFL_read_callback  */
  1747.  
  1748.  
  1749.  
  1750.                            /*CodeRef-mark*/
  1751.  
  1752. long int WFL_popup_info ( startRow, startCol, maxRows,
  1753.           banner, element_list, window_ptr)
  1754. int                   startRow;
  1755. int                   startCol;
  1756. int                  maxRows;
  1757. char                  *banner;
  1758. char                  *element_list[];
  1759. struct window_struct **window_ptr;
  1760.   /*
  1761.    *   Popup an info message on-the-fly.
  1762.    *   Caller must erase and deallocate the window.
  1763.    *   Return value: status of
  1764.    */
  1765.                            /*CodeRef-mark*/
  1766. {
  1767.      int                   stat;
  1768.  
  1769.      stat = WFL_new_dyna_window (window_ptr, banner);
  1770.  
  1771.      WFL_set_dyna_window  (startRow, startCol, maxRows,
  1772.                     element_list, *window_ptr);
  1773.  
  1774.      WFL_put_dyna_info (*window_ptr, element_list);
  1775.  
  1776.      return (stat);
  1777. }  /* end WFL_popup_info */
  1778.  
  1779.  
  1780.  
  1781.                            /*CodeRef-mark*/
  1782.  
  1783. void WFL_put_dyna_info (window_ptr, element_list)
  1784. struct window_struct  *window_ptr;
  1785. char                  *element_list[];
  1786. /*
  1787.  *  This function puts the element list in the info window.
  1788.  */
  1789.                            /*CodeRef-mark*/
  1790. {
  1791.      int num_elements = string_count(element_list);
  1792.      struct menu_element_struct  **tempMenu;
  1793.  
  1794.      WFL_draw_window (window_ptr);
  1795.  
  1796.      tempMenu = WFL_new_dyna_menu (element_list);
  1797.  
  1798.      WFL_load_menu (tempMenu, num_elements, window_ptr, 0, 0);
  1799.  
  1800.      WFL_delete_dyna_menu (tempMenu, element_list);
  1801.  
  1802. } /* end WFL_put_dyna_info */
  1803.  
  1804.  
  1805.  
  1806.                            /*CodeRef-mark*/
  1807.  
  1808.